package mskruch.gps.calculation;

import gpstools.TrainingPoint;
import mskruch.gps.Point;
import mskruch.gps.PointFactory;

/**
 * @author Marcin Skruch
 */
public class MskElevationCalculator implements ElevationCalculator {
    private static final double MINIMUM_DIFFERENCE = 2.5;

    private Point last = null;

    private double elevationGain = 0;
    private double elevationLoss = 0;
    private double elevation = 0;

    @Override
    public ElevationCalculator add(Point point) {
		if (point.getElevation() == null) {
			return this;
		}

        if (this.last != null) {
            /* not first point */
            double newElevation = point.getElevation();
            double difference = Math.abs(newElevation - this.elevation);
            if (difference >= MINIMUM_DIFFERENCE) {
                if (newElevation > this.elevation) {
                    this.elevationGain += difference;
                } else {
                    this.elevationLoss += difference;
                }
                this.elevation = newElevation;
            }
        } else {
            this.elevation = point.getElevation();
        }
        this.last = point;
        return this;
    }
    
    @Override
    public void add(TrainingPoint point) {
        add(PointFactory.newPoint(point));
    }

    @Override
    public double getElevationLoss() {
        if (this.last == null || this.last.getElevation() > this.elevation) {
            return this.elevationLoss;
        } else {
            return this.elevationLoss + (this.elevation - this.last.getElevation());
        }
    }

    @Override
    public double getElevationGain() {
        if (this.last == null || this.last.getElevation() < this.elevation) {
            return this.elevationGain;
        } else {
            return this.elevationGain + (this.last.getElevation() - this.elevation);
        }
    }

    @Override
    public Double getCurrent() {
        if (last == null) {
            return null;
        }
        return this.elevation;
    }

}
